(module data scheme

;; tells scheme to provide everything in this file to anyone who requires it
(provide (all-defined-out))

;; we need world.ss for check-expect, etc.
(require (lib "world.ss" "teachpack" "htdp"))
(require lang/htdp-intermediate-lambda)

(define-struct board (territories continents players state))
;; A Board is a (make-board [ListOf Territory]
;;                          [Listof Continent]
;;                          [Listof Player]
;;                          State
;; Where territories is a list of territories on the game board
;;       continents is a list of continents on the game board
;;       players is a list of players on the game board
;;       state is the current state information of the game board

;; A State is a 4 (FOUR) element list:
;; the first element is a symbol representing the state
;;; either:
;;; 'init
;;; 'p1
;;; 'p2-origin
;;; 'p2-victim
;;; 'p3-0
;;; 'p3-origin
;;; 'p3-dest

;; the second and third elements are extra data about the state.

;; the fourth element is a list of buttons that are associated with the current state
;; these will be drawn onto the ui.

;;; p1:
;;; - (list symbol number empty empty)
;; the number is the number of units remaining that can be placed
;; the remaining two fields are unused.

;;; p2-origin
;;; - (list symbol empty empty [listof ui-element])
;; there is no data to be stored here other than ui-elements and the symbol
;; representing the current phase.

;;; p2-victim
;;; - (list symbol Territory empty [listof ui-element])
;; We store the territory that the person is attacking from and attempt to
;; determine what territory that they are attacking using that data.

;;; p3-origin
;;; - (list symbol empty empty [listof ui-element])
;; we store nothing here besides the phase and ui-elements that can be manipulated
;; on the screen. The player will click a territory that they want to draw
;; reenforcements from.

;;; p3-destination
;;; - (list symbol Territory Number [listof ui-element])
;; we store the territory that the player has chosen to draw reenforcments from
;; and the number of units that are remaining to be placed. We need to be able
;; to draw a line from the originating territory to the reenforced one, so
;; we need both to find the path.

;; What's this last list of ui-element doing? I'm doing reinforcement via neighbors, also
;; something that is in the territory struct itself.


(define-struct button (name widget))
;; A Button is a (make-button Symbol Widget)
;; name – text displayed on the button
;; widget - the graphical representation of the button on screen (no text)

(define-struct dialog (name message buttons))
;; A Dialog is a (make-dialog Symbol String [ListOf Button]
;; name - the name of this dialog
;; message - the prompt displayed to the user
;; buttons - the list of buttons to display
;;      NOTE: The location of the buttons is ignored, they are auto placed

(define-struct territory (name continent units neighbors player widget))
;; A Territory is a:
;; (make-territory Symbol Symbol Number [ListOf Symbol] Player Widget)
;; where name is the name of the territory
;;       units is the number of men in the territory
;;       neighbors is the list off all territories bordering this territory
;;       player is the player who controls this territory
;;       widget is the graphical representation of the button on screen

;; A Combo-Image is either:
;; - Image
;; - (cons Image Combo-Image)
;;   for more information regarding images see:
;;   http://docs.plt-scheme.org/teachpack/image.html

(define-struct widget (x y image))
;; A Widget is a:
;; (make-widget Number Number Image)
;; Where x is the x coordinate of the center of the widget
;;       y is the y coordinate of the center of the widget
;;       image is the Combo-Image representing the shape

;; A State is a (cons Symbol (cons Symbol (cons X)))
;; where the first and second symbols are the current player and phase.
;; and x is a list according to the diagram listed below:

(define-struct continent (name value))
;; A Continent is a (make-continent symbol number)
;; name – a symbol representing the name of the continent
;; value – the number of reenforcements a player receives for owning this continent

;; A UI-Element is either:
;; - a Territory
;; - a Button
;; - a Dialog
  
;; A Player is one of:
;; 'red
;; 'blue
;; 'green
;; 'orange
;; 'purple
;; 'grey
;; 'black


#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|#
;; GLOBAL CONSTANTS

;; the dimensions of the screen
(define SCREEN-HEIGHT 600)
(define SCREEN-WIDTH  800)

#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|#
;; SAMPLE DATA FOR TESTING PURPOSES:


;;;; SAMPLE CONTINENTS ;;;;

;; mini-asia
(define mini-asia (make-continent 'asia 2))
;; mini-europe
(define mini-europe (make-continent 'europe 3))
;; mini-america
(define mini-america (make-continent 'america 2))

(define continent-list (list mini-asia mini-europe mini-america))

;;;; SAMPLE SHAPES/POSITIONS FOR SAMPLE TERRITORIES ;;;;

;; colors for continents
(define lblue (make-color 200 200 255))
(define pink (make-color 255 200 200))
(define lgreen (make-color 200 255 200))


;; mini-america shapes
(define shape-canada (list (rectangle 120 100 'solid 'blue)
                           (rectangle 115 95 'solid pink)))
(define shape-usa    (list (rectangle 100 100 'solid 'blue)
                           (rectangle 95 95 'solid pink)))
(define shape-mexico (list (rectangle 40 50 'solid 'blue)
                           (rectangle 35 45 'solid pink)))
(define shape-sa     (list (rectangle 70 130 'solid 'red)
                           (rectangle 65 125 'solid pink)))

(define widget-canada (make-widget 80 70 shape-canada))
(define widget-usa    (make-widget 80 170 shape-usa))
(define widget-mexico (make-widget 100 245 shape-mexico))
(define widget-sa     (make-widget 95 335 shape-sa))

;; mini-europe shapes
(define shape-france       (list (rectangle 70 70 'solid 'blue)
                                 (rectangle 65 65 'solid lblue)))
(define shape-germany      (list (rectangle 70 50 'solid 'red)
                                 (rectangle 65 45 'solid lblue)))
(define shape-mideast      (list (rectangle 30 60 'solid 'red)
                                 (rectangle 25 55 'solid lblue)))
(define shape-africa-north (list (rectangle 130 60 'solid 'blue)
                                 (rectangle 125 55 'solid lblue)))
(define shape-africa-south (list (rectangle 70 130 'solid 'blue)
                                 (rectangle 65 125 'solid lblue)))

(define widget-france       (make-widget 240 185 shape-france))
(define widget-germany      (make-widget 310 175 shape-germany))
(define widget-mideast      (make-widget 290 230 shape-mideast))
(define widget-africa-north (make-widget 255 310 shape-africa-north))
(define widget-africa-south (make-widget 265 405 shape-africa-south))

;; mini-asia shapes
(define shape-russia    (list (rectangle 200 100 'solid 'red)
                              (rectangle 195 95 'solid lgreen)))
(define shape-china     (list (rectangle 100 100 'solid 'red)
                              (rectangle 95 95 'solid lgreen)))
(define shape-australia (list (rectangle 100 80 'solid 'red)
                              (rectangle 95 75 'solid lgreen)))

(define widget-russia    (make-widget 445 170 shape-russia))
(define widget-china     (make-widget 495 270 shape-china))
(define widget-australia (make-widget 610 380 shape-australia))

;; connector line widgets

;; lines draw weirdly in the image teachpack....

  ;;for example, adding a line to an image is:
  ;;(add-line (i) 80 70 240 185 'black) should add a line to image I going from canada to france.



;;;; ADJCENCY LISTS FOR TERRITORIES ;;;;

;; mini-america lists
(define adj-canada '(usa france))
(define adj-usa    '(canada mexico china))
(define adj-mexico '(usa sa))
(define adj-sa     '(mexico africa-north))

;; mini-europe lists
(define adj-france       '(canada germany mideast))
(define adj-germany      '(france mideast russia))
(define adj-mideast      '(germany africa-north france))
(define adj-africa-north '(mideast africa-south sa))
(define adj-africa-south '(africa-north))

;; mini-asia lists
(define adj-russia    '(germany china))
(define adj-china     '(russia australia usa))
(define adj-australia '(china))


;;
;; @territories
;; The normal territories
;;;;;;;;;;;;;;;

;; american territories
(define ter-canada (make-territory 'canada 'america 0 adj-canada 'unowned widget-canada))
(define ter-usa    (make-territory 'usa 'america 0 adj-usa 'unowned widget-usa))
(define ter-mexico (make-territory 'mexico 'america 0 adj-mexico 'unowned widget-mexico))
(define ter-sa     (make-territory 'sa 'america 0 adj-sa 'unowned widget-sa))

;; european territories
(define ter-france       (make-territory 'france 'europe 0 adj-france 'unowned widget-france))
(define ter-germany      (make-territory 'germany 'europe 0 adj-germany 'unowned widget-germany))
(define ter-mideast      (make-territory 'mideast 'europe 0 adj-mideast 'unowned widget-mideast))
(define ter-africa-north (make-territory 'africa-north 'europe 0 adj-africa-north 'unowned widget-africa-north))
(define ter-africa-south (make-territory 'africa-south 'europe 0 adj-africa-south 'unowned widget-africa-south))

;; asian territories
(define ter-russia    (make-territory 'russia 'asia 0 adj-russia 'unowned
                                      widget-russia))
(define ter-china     (make-territory 'china 'asia 0 adj-china 'unowned
                                      widget-china))
(define ter-australia (make-territory 'australia 'asia 0 adj-australia 'unowned
                                      widget-australia))

;; THE STARTING TERRITORY LIST:
(define territory-list-base
  (list ter-canada ter-usa ter-mexico ter-sa ter-france ter-germany ter-mideast
        ter-africa-north ter-africa-south ter-russia ter-china ter-australia))

;; A Test territory list, for testing
(define test-ter-list
  (list ter-canada ter-usa))

;; A Dummy canada
(define fake-canada (make-territory 'canada 0 0 0 0 0))

;; A Fake Board for Testing
(define ter-update-board (make-board test-ter-list empty empty (list 'p1 10 empty empty)))

;; An updated america
(define ter-usa-plus1    (make-territory 'usa 'america 1 adj-usa 'unowned widget-usa))

;; An updated canasa
(define ter-canada-plus1 (make-territory 'canada 'america 1 adj-canada 'unowned widget-canada))


;;
;; @buttons
;; The buttons
;;;;;;;;;;;;;;;
(define next-phase (make-button 'next-phase
                                (make-widget (- SCREEN-WIDTH 105)
                                             (- SCREEN-HEIGHT 50)
                                             (rectangle 100 40 'solid 'yellow))))
(define cancel (make-button 'cancel
                            (make-widget (- SCREEN-WIDTH 190)
                                         (- SCREEN-HEIGHT 50)
                                         (rectangle 80 40 'solid 'orange))))

(define yes-button (make-button 'yes
                                (make-widget (- SCREEN-WIDTH 85)
                                             (- SCREEN-HEIGHT 50)
                                             (rectangle 80 40 'solid 'green))))
(define no-button (make-button 'no
                               (make-widget (- SCREEN-WIDTH 170)
                                            (- SCREEN-HEIGHT 50)
                                            (rectangle 80 40 'solid 'red))))

;;
;; END OF
;; The buttons
;;;;;;;;;;;;;;;

;;
;; @dialogs
;; The Dialogs
;;;

;;
;; END OF
;; The Dialogs
;;;;;;;;;;;;;;;

;;
;; @buttonlists @incomplete
;; The button lists for each phase
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define phase2-origin-buttons (list next-phase))
(define phase2-victim-buttons (list next-phase cancel))
(define phase3-origin-buttons (list next-phase))
(define phase2-continue-buttons (list yes-button no-button))

;;
;; END OF
;; The button lists for each phase
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @gplayers
;; The g- prefixed players
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define g-players '(red blue))

;;
;; END OF
;; The g- prefixed players
;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @gterritoriers
;; The g- prefixed territoriers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; american territories
(define g-ter-canada (make-territory 'canada 'america 8 adj-canada 'blue widget-canada))
(define g-ter-usa    (make-territory 'usa    'america 3 adj-usa    'blue widget-usa))
(define g-ter-mexico (make-territory 'mexico 'america 7 adj-mexico 'blue widget-mexico))
(define g-ter-sa     (make-territory 'sa     'america 7 adj-sa     'red  widget-sa))

;; european territories
(define g-ter-france       (make-territory 'france       'europe 4 adj-france       'blue widget-france))
(define g-ter-germany      (make-territory 'germany      'europe 4 adj-germany      'red  widget-germany))
(define g-ter-mideast      (make-territory 'mideast      'europe 3 adj-mideast      'red  widget-mideast))
(define g-ter-africa-north (make-territory 'africa-north 'europe 5 adj-africa-north 'blue widget-africa-north))
(define g-ter-africa-south (make-territory 'africa-south 'europe 2 adj-africa-south 'blue widget-africa-south))

;; asian territories
(define g-ter-russia    (make-territory 'russia    'asia 9 adj-russia    'red widget-russia))
(define g-ter-china     (make-territory 'china     'asia 4 adj-china     'red widget-china))
(define g-ter-australia (make-territory 'australia 'asia 1 adj-australia 'red widget-australia))

;; the list of territores AT THIS POINT in our game
(define g-territory-list-current
  (list g-ter-canada g-ter-usa g-ter-mexico g-ter-sa g-ter-france g-ter-germany g-ter-mideast
        g-ter-africa-north g-ter-africa-south g-ter-russia g-ter-china g-ter-australia))

;; germany with 1 unit
(define g-ter-germany*      (make-territory 'germany      'europe 1 adj-germany      'red  widget-germany))
  
;; for testing
(define g-territory-list-current-germ-robbed
  (list g-ter-canada g-ter-usa g-ter-mexico g-ter-sa g-ter-france g-ter-germany* g-ter-mideast
        g-ter-africa-north g-ter-africa-south g-ter-russia g-ter-china g-ter-australia))
;;
;; END OF
;; The g- prefixed territories
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @gstates
;; The g- prefixed states
;;;;;;;;;;;;;;;;;;;;;;;;;;
(define g-state-p1 (list 'p1 10 empty empty))
(define g-state-p2-o (list 'p2-origin empty empty phase2-origin-buttons))
(define g-state-p2-victim-germany-blue (list 'p2-victim
                                            g-ter-germany
                                            empty
                                            phase2-victim-buttons))
(define g-state-p3-o (list 'p3-origin empty empty phase3-origin-buttons))
(define g-state-p3-d (list 'p3-dest ter-canada 0 phase3-origin-buttons))

;; used for the new state machine implementation of attacking
(define g-state-p2-from (list 'p2-origin empty empty phase2-origin-buttons))
(define g-state-p2-to (list 'p2-victim
                            (list g-ter-germany)
                            empty
                            phase2-victim-buttons))
(define g-state-p2-commence-attack (list 'p2-victim
                                         (list g-ter-germany g-ter-france)
                                         'commence-attack
                                         phase2-victim-buttons))
(define g-state-p2-continue? (list 'p2-victim
                                   (list g-ter-germany g-ter-france)
                                   'continue?
                                   phase2-continue-buttons))

;;
;; END OF
;; The g- prefixed states
;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;; @boards
;; Board data that is used for testing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define board-blank (make-board territory-list-base
                                continent-list
                                g-players
                                g-state-p1))
(define g-board-p1 (make-board g-territory-list-current
                               continent-list
                               g-players
                               g-state-p1))
(define board-blank-state2 (make-board territory-list-base
                                       continent-list
                                       g-players
                                       g-state-p2-o))
(define board-blank-player-blue (make-board territory-list-base
                                            continent-list
                                            `(blue red)
                                            g-state-p2-o))
(define running-game-p2-o (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p2-o))
(define running-game-p2-victim (make-board g-territory-list-current
                                           continent-list
                                           g-players
                                           g-state-p2-victim-germany-blue))
;; used in testing the new attack functions
(define test-board-p2-from (make-board g-territory-list-current
                                       continent-list
                                       g-players
                                       g-state-p2-from))
(define test-board-p2-to (make-board g-territory-list-current
                                     continent-list
                                     g-players
                                     g-state-p2-to))
(define test-board-p2-commence-attack (make-board g-territory-list-current
                                       continent-list
                                       g-players
                                       g-state-p2-commence-attack))
(define test-board-p2-continue? (make-board g-territory-list-current
                                            continent-list
                                            g-players
                                            g-state-p2-continue?))

(define running-game-p3-o (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p3-o))
(define running-game-p3-d-0 (make-board g-territory-list-current
                                      continent-list
                                      g-players
                                      g-state-p3-d))
;;
;; END OF
;; Board data that is used for testing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;; phase 2 Attack Defend Test Data
(define g-ter-canada-post-attack (make-territory 'canada 'america 1 adj-canada 'blue widget-canada))
(define g-ter-usa-post-attack    (make-territory 'usa    'america 7 adj-usa    'blue widget-usa))

(define g-ter-mideast-post-attack      (make-territory 'mideast      'europe 4 adj-mideast      'red  widget-mideast))
(define g-ter-africa-north-post-attack (make-territory 'africa-north 'europe 1 adj-africa-north 'blue widget-africa-north))

) ;; end of module
